package facade;
import java.rmi.RemoteException;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;

import javax.ejb.EJBTransactionRolledbackException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import exceptions.LogNOKException;
import exceptions.VentaNOKException;
import vo.ArticuloVO;
import vo.CarritoVO;
import vo.ConfiguracionVO;
import vo.ElectrodomesticoVO;
import vo.InfantilVO;
import vo.ModaVO;
import vo.MuebleVO;
import vo.VentaVO;


public class BD{
	
	private static BD instance;
	
	public static BD getInstance() throws EJBTransactionRolledbackException, RemoteException{
		if(instance == null){
			instance = new BD();
		}
		return instance;
	}
	
	private BD() throws RemoteException, EJBTransactionRolledbackException {
		super();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Facade getConexion(){
		
		Facade facade = null;
		
		try {
			String naming = "PortalWeb_EAR/FacadeBean/remote";
			Hashtable props = new Hashtable();
			props.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
			props.put(InitialContext.PROVIDER_URL,"jnp://127.0.0.1:1099");
			InitialContext ic = new InitialContext(props);
			facade = (Facade) ic.lookup(naming);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return facade;
	} 
	
	public boolean existeUsuario(String u, String p){
		Facade f = getFacade();
		return f.iniciarSesion(u, p);
		
	}
	
	public void updateConfiguracion(ConfiguracionVO c){
		Facade f = getFacade();
		f.updateConfiguracion(c);
		
	}
	
	public List<ConfiguracionVO> obtenerConfiguraciones(){
		Facade f = getFacade();
		return f.obtenerConfiguraciones();
		
	}
	
	
	public ConfiguracionVO obtenerConfiguracionSeleccionada(int id){
		Facade f = getFacade();
		return f.obtenerConfiguracionSeleccionada(id);
		
	}
	
	public void agregarAlCarrito(int codigo, int cantidad){
		Facade f = getFacade();
		f.agregarAlCarrito(codigo, cantidad);
	}
	
	
	public List<VentaVO> getVentas(){
		Facade f = getFacade();
		return f.getVentas();
		
	}

	private Facade getFacade() {
		Facade f = new FacadeBean();
		try {
			f = lookupRemoteStatefulCounter();
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return f;
	}
	
	
	private static Facade lookupRemoteStatefulCounter() throws NamingException {
        //final Hashtable jndiProperties = new Hashtable();
        //jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        final Context context = ClientUtility.getInitialContext();
        /*
        The app name is the EAR name of the deployed EJB without .ear suffix.
        Since we haven't deployed the application as a .ear,
        the app name for us will be an empty string
        */
            String appName = "PortalWeb_EAR";

            /* The module name is the JAR name of the deployed EJB
            without the .jar suffix.
            */
            String moduleName = "PortalWeb_Server";

        /*AS7 allows each deployment to have an (optional) distinct name.
        This can be an empty string if distinct name is not specified.
        */
            String distinctName = "";

            // The EJB bean implementation class name
            String beanName = FacadeBean.class.getSimpleName();

            // Fully qualified remote interface name
            final String interfaceName = Facade.class.getName();

            // Create a look up string name
            String name = "ejb:" + appName + "/" + moduleName + "/" +
                distinctName    + "/" + beanName + "!" + interfaceName;
            return (Facade)context.lookup(name);
    }

	public List<ArticuloVO> getArticulos() {
		Facade f = getFacade();
		return f.getArticulos();
		
	}


	public ElectrodomesticoVO getElectrodomestico(int codigo) {
		Facade f = getFacade();
		return f.getElectrodomestico(codigo);
	}

	public InfantilVO getInfantil(int codigo) {
		Facade f = getFacade();
		return f.getInfantil(codigo);
	}

	public ModaVO getModa(int codigo) {
		Facade f = getFacade();
		return f.getModa(codigo);
	}

	public MuebleVO getMueble(int codigo) {
		Facade f = getFacade();
		return f.getMueble(codigo);
	}
	
	public List<ArticuloVO> buscarArticulo(int codigo, String nombre, String descripcion, String marca, String origen){
		Facade f = getFacade();
		return f.buscarArticulo(codigo, nombre, descripcion, marca, origen);
	}

	public List<ArticuloVO> buscarElectrodomestico(int codigo,
			String nombre, String descripcion, String marca, String origen) {
		Facade f = getFacade();
		return f.buscarElectrodomestico(codigo, nombre, descripcion, marca, origen);
	}
	
	public List<ArticuloVO> buscarInfantil(int codigo,
			String nombre, String descripcion, String marca, String origen) {
		Facade f = getFacade();
		return f.buscarInfantil(codigo, nombre, descripcion, marca, origen);
	}
	
	public List<ArticuloVO> buscarModa(int codigo,
			String nombre, String descripcion, String marca, String origen) {
		Facade f = getFacade();
		return f.buscarModa(codigo, nombre, descripcion, marca, origen);
	}
	
	public List<ArticuloVO> buscarMueble(int codigo,
			String nombre, String descripcion, String marca, String origen) {
		Facade f = getFacade();
		return f.buscarMueble(codigo, nombre, descripcion, marca, origen);
	}

	public CarritoVO getCarrito() {
		Facade f = getFacade();
		return f.getCarrito();
	}

	public boolean actualizarRanking(String json) {
		Facade f = getFacade();
		return f.actualizarRanking(json);
		
	}

	public void confirmarCarrito() {
		Facade f = getFacade();
		try {
			f.confirmarCarrito();
		} catch (LogNOKException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (VentaNOKException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void sacarArticuloCarrito(int codigo){
		Facade f = getFacade();
		f.sacarArticuloCarrito(codigo);
	}

	public void cambiarCantidadArticuloCarrito(int codigo, int cantidad) {
		Facade f = getFacade();
		f.cambiarCantidadArticuloCarrito(codigo, cantidad);
	}

	public List<VentaVO> getVentasUsuario() {
		Facade f = getFacade();
		return f.getVentasUsuario();
	}
}

class ClientUtility {
	 
    private static Context initialContext;
 
    private static final String PKG_INTERFACES = "org.jboss.ejb.client.naming";
 
    public static Context getInitialContext() throws NamingException {
        if (initialContext == null) {
            Properties properties = new Properties();
            properties.put(Context.URL_PKG_PREFIXES, PKG_INTERFACES);
 
            initialContext = new InitialContext(properties);
        }
        return initialContext;
    }
}